package com.qsl.ssyx.activity.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qsl.ssyx.activity.mapper.CouponRangeMapper;
import com.qsl.ssyx.activity.service.CouponRangeService;
import com.qsl.ssyx.activity.service.CouponUseService;
import com.qsl.ssyx.client.product.ProductFeignClient;
import com.qsl.ssyx.enums.CouponRangeType;
import com.qsl.ssyx.enums.CouponStatus;
import com.qsl.ssyx.enums.CouponType;
import com.qsl.ssyx.model.activity.CouponInfo;
import com.qsl.ssyx.activity.mapper.CouponInfoMapper;
import com.qsl.ssyx.activity.service.CouponInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qsl.ssyx.model.activity.CouponRange;
import com.qsl.ssyx.model.activity.CouponUse;
import com.qsl.ssyx.model.order.CartInfo;
import com.qsl.ssyx.model.product.Category;
import com.qsl.ssyx.model.product.SkuInfo;
import com.qsl.ssyx.vo.activity.CouponRuleVo;
import com.sun.xml.internal.fastinfoset.util.LocalNameQualifiedNamesMap;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 优惠券信息 服务实现类
 * </p>
 *
 * @author 青衫泪
 * @since 2023-08-28
 */
@Service
public class CouponInfoServiceImpl extends ServiceImpl<CouponInfoMapper, CouponInfo> implements CouponInfoService {

    @Autowired
    private CouponRangeService couponRangeService;

    @Autowired
    private CouponUseService couponUseService;

    @Autowired
    private ProductFeignClient productFeignClient; // 远程调用

    //    条件分页查询
    @Override
    public IPage<CouponInfo> selectPage(Page<CouponInfo> pageParam) {
        Page<CouponInfo> couponInfoPage = baseMapper.selectPage(pageParam, null);

        // 设置 购物券类型，使用范围
        List<CouponInfo> records = couponInfoPage.getRecords();
        records.stream().forEach(
                item -> {
                    item.setCouponTypeString(item.getCouponType().getComment()); // 购物券类型 1 现金券 2 满减券
                    item.setRangeTypeString(item.getRangeType().getComment());    // 使用范围[1->全场通用；2->指定分类；3->指定商品]
                }
        );
        return couponInfoPage;
    }

    //    新增优惠卷规则
    @Override
    public boolean saveCouponRule(CouponRuleVo couponRuleVo) {
        // 根据优惠卷ID删除 优惠劵范围表
        LambdaQueryWrapper<CouponRange> lqw = new LambdaQueryWrapper<>();
        lqw.eq(CouponRange::getCouponId, couponRuleVo.getCouponId());
        couponRangeService.remove(lqw);

        // 更新 couponInfo-优惠卷信息   // 主要复制优惠券id,范围类型,金额，使用门槛 0->没门槛，优惠券范围描述
        CouponInfo couponInfo = baseMapper.selectById(couponRuleVo.getCouponId());
        couponInfo.setRangeType(couponRuleVo.getRangeType());
        couponInfo.setConditionAmount(couponRuleVo.getConditionAmount());
        couponInfo.setAmount(couponRuleVo.getAmount());
        couponInfo.setConditionAmount(couponRuleVo.getConditionAmount());
        couponInfo.setRangeDesc(couponRuleVo.getRangeDesc());
        baseMapper.updateById(couponInfo);

        // 新增 couponRange-优惠卷规则
        List<CouponRange> couponRangeList = couponRuleVo.getCouponRangeList();
        for (CouponRange couponRange : couponRangeList) {
            couponRange.setCouponId(couponRuleVo.getCouponId());
            couponRangeService.save(couponRange);
        }
        return true;
    }

    //    根据优惠卷id查询
    @Override
    public Map<String, Object> findCouponRuleList(Long couponId) {
        // 根据id查询优惠卷信息表
        CouponInfo couponInfo = baseMapper.selectById(couponId);

        // 根据id查询优惠卷范围表
        LambdaQueryWrapper<CouponRange> lqw = new LambdaQueryWrapper<>();
        lqw.eq(CouponRange::getCouponId, couponId);
        List<CouponRange> couponRangeList = couponRangeService.list(lqw);

        //couponRangeList获取所有range_id
        //// 如果规则类型 通用，无须返回数据
        //// 如果规则类型 SKU      range_id就是skuId值
        //// 如果规则类型 CATEGORY range_id就是分类Id值
        List<Long> longList = couponRangeList.stream().map(CouponRange::getCouponId).collect(Collectors.toList());

        // 封装最终返回数据
        Map<String, Object> result = new HashMap<>();

        // 根据规则类型不同，返回不同数据
        if (!CollectionUtils.isEmpty(couponRangeList)) { // 集合数据不为空
            if (couponInfo.getRangeType() == CouponRangeType.SKU) { // 若规则类型是SKU,得到skuId

                for (Long skuId : longList) {
                    // 根据skuid查询商品集合
                    List<SkuInfo> skuInfoList = productFeignClient.getSkuInfoList(skuId);
                    result.put("skuInfoList", skuInfoList);
                }
            } else if (couponInfo.getRangeType() == CouponRangeType.CATEGORY) { // 若规则类型是分类,得到分类id
                // 根据categoryid查询分类集合
                List<Category> categoryList = productFeignClient.getCategoryList(longList);
                result.put("categoryList", categoryList);
            }
        }
        return result;
    }

    //2 根据skuId+userId查询优惠卷信息
    @Override
    public List<CouponInfo> getCouponInfoBySkuIdAndUserId(Long skuId, Long userId) {
//        根据skuId获取商品信息
        SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);

        // skuId + 分类id + userId
        List<CouponInfo> couponInfoList = baseMapper.getCouponInfoBySkuIdAndUserIdList(skuId, skuInfo.getCategoryId(), userId);
        return couponInfoList;
    }

    //  获取购物车删除可以使用优惠卷列表
    @Override
    public List<CouponInfo> findCartCouponInfo(List<CartInfo> cartInfoList, Long userId) {
        // 根据userId获取用户全部优惠卷： coupon_use连coupon_info
        List<CouponInfo> userAllCouponInfoList = baseMapper.selectCartCouponInfoList(userId);

        if (!CollectionUtils.isEmpty(userAllCouponInfoList)) {
            return new ArrayList<CouponInfo>();
        }

        // 2.获取所有优惠卷id列表
        List<Long> couponIdList = userAllCouponInfoList.stream().map(item -> item.getId()).collect(Collectors.toList());

        // 3.查询优惠卷对应范围 coupon_range
        LambdaQueryWrapper<CouponRange> lqw = new LambdaQueryWrapper<>();
        // id in (1,2,3)
        lqw.in(CouponRange::getCouponId, couponIdList);
        List<CouponRange> couponRangeList = couponRangeService.list(lqw);

        // 4 获取优惠卷id,对应的商品id（skuId）列表
        Map<Long, List<Long>> couponIdToSkuIdMap = this.findcouponIdToSkuIdMap(cartInfoList, couponRangeList);


        // 5.遍历全部优惠卷集合，判断优惠卷类型

        return userAllCouponInfoList;
    }

    //    根据购物车商品和优惠卷id获取优惠卷信息
    @Override
    public CouponInfo findRangeSkuIdList(List<CartInfo> cartInfoList, Long couponId) {
        // 查询优惠卷信息
        CouponInfo couponInfo = baseMapper.selectById(couponId);
        if (couponInfo == null) {
            return null;
        }

        //根据couponId查询优惠卷范围
        List<CouponRange> couponRangeList = couponRangeService.getCouponRangeByCouponId(couponId);

        // 查询商品信息
        Map<Long, List<Long>> couponIdToSkuIdMap = this.findcouponIdToSkuIdMap(cartInfoList, couponRangeList);
        // 遍历map,获取value值，
        List<Long> skuIdList = couponIdToSkuIdMap.entrySet().iterator().next().getValue();
        couponInfo.setSkuIdList(skuIdList);
        return couponInfo;
    }

    //  根据用户id、优惠卷id、优惠卷与用户ID， 修改优惠卷状态-已使用
    @Override
    public boolean updateCouponInfoUseStatus(Long couponId, Long userId, Long id) {
        LambdaQueryWrapper<CouponUse> lqw = new LambdaQueryWrapper<>();
        lqw.eq(CouponUse::getId, id);
        lqw.eq(CouponUse::getCouponId, couponId);
        lqw.eq(CouponUse::getUserId, userId);
        CouponUse couponUse = couponUseService.getOne(lqw);

        // 修改优惠卷状态
        couponUse.setCouponStatus(CouponStatus.USED);

        boolean flag = couponUseService.updateById(couponUse);
        return flag;
    }

    //4 获取优惠卷id 对应skuId列表
    //优惠卷id进行分组，得到map集合
    private Map<Long, List<Long>> findcouponIdToSkuIdMap(List<CartInfo> cartInfoList, List<CouponRange> couponRangeList) {
        HashMap<Long, List<Long>> couponIdToSkuIdMap = new HashMap<>();

        // 根据优惠劵id分组
        Map<Long, List<CouponRange>> couponRangeToRangeListMap = couponRangeList.stream().collect(Collectors.groupingBy(couponRange -> couponRange.getCouponId()));

        // 遍历map集合
        Iterator<Map.Entry<Long, List<CouponRange>>> iterator = couponRangeToRangeListMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<Long, List<CouponRange>> entry = iterator.next();
            Long couponId = entry.getKey();
            List<CouponRange> rangeList = entry.getValue();

            // 创建集合 set
            HashSet<Long> skuIdSet = new HashSet<>();
            for (CartInfo cartInfo : cartInfoList) {
                for (CouponRange couponRange : rangeList) {
                    //判断优惠价类型为sku,分类，全场通用
                    if (couponRange.getRangeType() == CouponRangeType.SKU
                            && couponRange.getRangeId().longValue() == cartInfo.getSkuId().longValue()) { // sku
                        skuIdSet.add(cartInfo.getSkuId());
                    } else if (couponRange.getRangeType() == CouponRangeType.CATEGORY
                            && couponRange.getRangeId().longValue() == cartInfo.getCategoryId().longValue()) { // 分类
                        skuIdSet.add(cartInfo.getSkuId());
                    } else {

                    }
                }
            }
            couponIdToSkuIdMap.put(couponId, new ArrayList<>(skuIdSet));
        }
        return couponIdToSkuIdMap;
    }


}
